/*************************************************************************
	> File Name: cond.c
	> Author: 
	> Mail: 
	> Created Time: 2015年01月07日 星期三 23时25分32秒
 ************************************************************************/

#include"errors.h"
#include<pthread.h>
#include<time.h>


typedef struct my_struct_tag {
    pthread_mutex_t     mutex;
    pthread_cond_t      cond;
    int                 value;
} my_struct_t;

my_struct_t data = {
    PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER,0
};

int hibernation = 1;

void *wait_thread(void *arg){
    int status;
    
    sleep(hibernation);
    if((status = pthread_mutex_lock(&data.mutex))){
        err_abort(status,"Lock mutex");
    }
    puts("wait thread locked");
    data.value = 1;
    printf("data.value %d\n",data.value);
    pthread_cond_signal(&data.cond);
    if(( status = pthread_mutex_unlock(&data.mutex) )){
        err_abort(status,"Unlock mutex");
    }
    puts("wait thread unlocked");
    return NULL;
}


int main(int argc,char *argv[]){
    int status;

    pthread_t wait_thread_id;
    struct timespec timeout;

    if (argc > 1){
        hibernation = atoi(argv[1]);
    }
    if((status = pthread_create(&wait_thread_id,NULL,wait_thread,NULL))){
        err_abort(status,"Create wait thread");
    }

    timeout.tv_sec = time(NULL) + 2;
    timeout.tv_nsec = 0;
    if((status = pthread_mutex_lock(&data.mutex))){
        err_abort(status,"lock mutex");
    }
    puts("main thread locked");
    while(data.value == 0){
        //pthread_cond_timewait will unlock the mutex and wait for the condition 
        //if condition is satisfied ,it will lock the mutex agagin
        status = pthread_cond_timedwait(&data.cond,&data.mutex,&timeout);
        if(status == ETIMEDOUT){ 
            printf("Condition wait timed out\n");
            break;
        }else if( status != 0 ){
            err_abort(status, "Waite on condition");
        }
    }
    if(data.value != 0){
        printf("conditaonn was signaled.\n");    
    }
    if((status = pthread_mutex_unlock(&data.mutex))){
        err_abort(status, "Unlock mutex");
    }
    puts("main thread unlocked");

    return 0;
}
